#pragma once
#ifndef _KH_ENGINE_COMMON_H
#define _KH_ENGINE_COMMON_H

#if defined(_DEBUG) && defined(KH_ENGINE_DEBUG_ALLOC)
# define _CRTDBG_MAP_ALLOC
# include <stdlib.h>
# include <crtdbg.h>
#endif

// Kharlia Core
#include <Kharlia/Core/Common.h>
#include <Kharlia/Core/Logger.h>
#include <Kharlia/Core/ObjectBase.h>
#include <Kharlia/Core/WeakPtr.h>

// Undef these to avoid annoying CEGUI warnings
#ifdef min
# undef min
#endif

#ifdef max
# undef max
#endif

// RakNet
#include <RakPeerInterface.h>
#include <RakNetTypes.h>
#include <MessageIdentifiers.h>
#include <BitStream.h>
#include <StringCompressor.h>
#include <RakNetTime.h>
#include <GetTime.h>
#include <ReplicaManager3.h>
#include <NetworkIDManager.h>

// DirectX10.1
#include <d3d10_1.h>
#include <D3DX10.h>

#undef main // Incompatible with Stackless

#ifdef KH_ENGINE_SOURCE
#  define KH_ENGINE_API __declspec(dllexport)
#else
#  define KH_ENGINE_API __declspec(dllimport)
#endif

/// Marks a function that calls a method of its name in Python
#define pycall
#define kh_pycall
/// Marks a function that is the C++ implementation of a pycall
#define pyimpl 
#define kh_pyimpl
/// Marks a function that must adhere to Python's MRO when calling
/// an base class function. Use GetSuper() to make the call.
#define pymro
#define kh_pymro

#include <Kharlia/Engine/Exceptions.h>

// Namespaces prototypes for aliases
namespace CEGUI {}
namespace RakNet {}

namespace kharlia {
    namespace ui = ::CEGUI;
    namespace rn = ::RakNet;

    namespace core { namespace util {}}

    namespace engine {
        using namespace core::util; // Utility functions
        using namespace core::exc; // Exceptions

        // Reference to kharlia.__engine module
        extern KH_ENGINE_API object GetInnerModuleAttr(str name);
        // Reference to kharlia._engine module
        extern KH_ENGINE_API object GetModuleAttr(str name);
        extern KH_ENGINE_API void SetModuleAttr(str name, object value);

        extern KH_ENGINE_API shared_ptr<core::FLogger> GetLogger();
        extern KH_ENGINE_API core::FLogger* GetLoggerPtr();
    }
}

#endif
